/*
 * imagen.h
 *
 *  Created on: 21-oct-2008
 *      Author: axel
 */

#ifndef IMAGEN_H_
#define IMAGEN_H_

#include <QtGui>
#include <QSize>
#include <QList>
#include <cmath>
#include "Graficas2D.h"
#include "punto.h"
#include "Ruido.h"
#include "filtro.h"

#include <iostream>
#include <QObject>

const int MAXCOLOR = 256;

using namespace std;

class Imagen : public QGraphicsView{
    Q_OBJECT

private:
    QImage imagen;
    QImage imagenBack;

    QPixmap pixmap;

    //Modificaciones con GraphicsView
    QGraphicsPixmapItem * pixMap;
    QGraphicsScene * scene;

    bool perfilActivo;
    bool moviendoLinea;

    QGraphicsLineItem * linea;
    QPointF origenF;
    QPointF destinoF;

    //Configuración de rubberBand
    bool rubberBandding;
    QRubberBand * rubberBand;
    QPoint origen;
    QPoint destino;

    QWidget * ventana;
    QString filename;
    int histograma[MAXCOLOR];



    int ajustar(double);
    void initGraphics();

    void lanzarFinLinea();
    QPoint pointf2point(const QPointF& punto);

    //funciones logarítmicas
    void func0(int * tabla);
    void func1(int * tabla, const double k);
    void func2(int * tabla, const double k, const int* histogramaA);
    void derivada(double * derivada, double * puntos, const int size);
    void suavizar(double * suavizado, double * puntos, const int size, const int k);

public:

    //constructores
    Imagen();
    void init(const QImage& im, const QString& titulo);
    Imagen(QWidget *parent,const QString & filename);
    Imagen(const Imagen& im);
    Imagen(const Imagen& im, const QString& titulo);
    Imagen(const QImage& im);
    Imagen(const QImage* im);
    Imagen(const QImage& im, const QString& titulo);
    Imagen(const QImage* im, const QString& titulo);
    Imagen(int w, int h);
    ~Imagen();

    //Getters
    const QImage& getImagen()const{return imagen;}
    QImage& getQImage() {return imagen;}
    const QString& getTitle()const{return filename;}
    void setTitle(const QString& titulo);

    void backup();
    void actualizar();
    void setFilename(const QString nombre);
    int getWidth()const;
    int getHeight()const;
    const QSize getSize()const{return imagen.size();}
    void getBrilloContraste(double & brillo, double & contraste)const;
    double getEntropia()const;
    void getRangoDinamico(int &, int &)const;
    void getHistogramaA(int *);
    void getHistogramaANorm(double *);
    //Archivo
    void save();
    void undo();
    //Edicion
    void makeHistograma();
    void toGray(double, double, double);
    //Imagen
    QWidget* pintarHistograma();
    QWidget* pintarHistogramaA();
    QImage getVecindad(int, int, int);
    QList <Punto> *brasenham(const int x1, const int y1, const int x2, const int y2);
    void perfil(QWidget ** graficas, const int x1, const int y1, const int x2, const int y2);

    //Transformación
    Imagen generarImagen(int * tabla);
    QImage* generarIma(const int * tabla);
    void modificarImagen(int tabla[MAXCOLOR]);
    Imagen ecualizar();
    QImage* digitalizar(const int tam);
    QImage* cuantizar(const int bits);
    QImage* logaritmo(const int numFunc, const double k);
    QImage* exponencial(const int numFunc, const double k);
    QImage* transformacionLineal(QList <QLine> lineas);
    QImage* espHisto(const double * histogramaA2);
    QImage* diferencia(const QImage& imagen2, const int dif);
    QImage* negativo();
    //Selección
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    QImage subImagen()const;
    void setPerfil(bool valor);
    const QGraphicsLineItem * getLinea(){return linea;}
    void mouseMove(QPoint, QRgb);
    //Ruido
    void aplicarRuidoImpulsivo(double porcentaje, Imagen * qRuido);
    void aplicarRuidoUniforme(double porcentaje, int n1, int n2, Imagen * qRuido);
    void aplicarRuidoGaussiano(double porcentaje, int n, Imagen * qRuido);
    //Filtro
    void aplicarFiltro(double *kernel,int kernelc, int kernelf, bool separable);
    void aplicarFiltroMediana(int f, int c);
    void aplicarFiltroKVecinos(int f, int c, int k);
    void aplicarFiltroModa(int f, int c);

        signals:
            void movido(QPoint punto, QRgb color);
    void finLinea(QPoint p1, QPoint p2);

public slots:
    void actualizarBrilloContraste(double m, double n);
};

#endif /* IMAGEN_H_ */
